package com.smart.car.gateway.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * @author zoutao.blog.csdn.net
 * @date 2021/4/29
 */
public class JwtUtils {
    /**
     * 私钥加密token
     * @param map           载荷中的数据
     * @param expireMinutes 过期时间，单位秒
     * @throws Exception
     */
    public static String generateToken(Map<String, Object> map, PrivateKey key, int expireMinutes) throws Exception {
        return Jwts.builder()
                .setClaims(map)
                //往后移动n分钟
                .setExpiration(DateUtil.offset(DateUtil.date(), DateField.MINUTE,expireMinutes).toSqlDate())
                .signWith(key, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 公钥解析token
     *
     * @param token 用户请求中的token
     * @throws Exception
     */
    private static Jws<Claims> parserToken(String token, PublicKey key) {
        return Jwts.parser().setSigningKey(key).parseClaimsJws(token);
    }

    /**
     * 获取token中的用户信息
     *
     * @param token 用户请求中的令牌
     * @return 用户信息
     */
    public static Map<String, Object> getInfoFromToken(String token, PublicKey key) {
        HashMap<String, Object> map = new HashMap<>(16);
        try {
            Jws<Claims> claimsJws = parserToken(token, key);
//            DateTime now = DateTime.now();
//            DateTime exp = new DateTime(claimsJws.getBody().getExpiration());
//            System.out.println((claimsJws.getBody().getExpiration().toString()));
            return claimsJws.getBody();
        } catch (Exception e) {
            e.printStackTrace();
            if (e.getMessage().contains("JWT expired")) {
                map.put("code:",500);
                map.put("msg:","认证过期");
            } else {
                map.put("code:",502);
                map.put("msg:","认证失败");
            }
            return map;
        }
    }

}
